package com.lordjoe.collectiveintelligence.svm.matchmaker;

import libsvm.*;

import java.util.*;
import java.text.*;

import com.lordjoe.collectiveintelligence.svm.*;
import com.lordjoe.collectiveintelligence.*;

/**
 * com.lordjoe.collectiveintelligence.svm.PotentialPair
 *
 * @author Steve Lewis
 * @date May 20, 2009
 */
public class PotentialPair 
{
    public static PotentialPair[] EMPTY_ARRAY = {};
    public static Class THIS_CLASS = PotentialPair.class;


    public static PotentialPair buildPotentialPair(String[] items)
    {
        int start = 0;
        int nItems = PotentialDate.NUMBER_TEXT_ITEMS;
        PotentialDate male = PotentialDate.buildPotentialDate(items, Sex.Male, start);
        PotentialDate female = PotentialDate.buildPotentialDate(items, Sex.Female, start + nItems);
        boolean compatable = SVMUtilities.from0or1(items[2 * nItems]);

        PotentialPair ret = new PotentialPair(male, female);
        ret.setCompatable(compatable);
        return ret;
    }
    public static PotentialPair buildPotentialPairVersion2(String[] items)
    {
        int start = 0;
        boolean compatable = SVMUtilities.from0or1(items[start++]);
        int nItems = PotentialDate.NUMBER_TEXT_ITEMS;
        PotentialDate male = PotentialDate.buildPotentialDate(items, Sex.Male, start);
        PotentialDate female = PotentialDate.buildPotentialDate(items, Sex.Female, start + nItems);

        start = 1 + 2 * nItems;
        LatLon maleLatLon =  new LatLon(items[start++]);
        male.setLatLon(maleLatLon);
        LatLon femaleLatLon =  new LatLon(items[start++]);
        female.setLatLon(femaleLatLon);

        double distance = Double.parseDouble(items[start++]);

        PotentialPair ret = new PotentialPair(male, female);
        ret.setCompatable(compatable);
        return ret;
    }

    private final PotentialDate m_Male;
    private final PotentialDate m_Female;
    private boolean m_Compatable;
    private Boolean m_PredictedCompatable;

    public PotentialPair(PotentialDate pMale, PotentialDate pFemale)
    {
        m_Male = pMale;
        m_Female = pFemale;
    }


    public boolean isPredictionCorrect()
    {
        if(m_PredictedCompatable == null)
            return true;
        boolean b = isCompatable();
        boolean predictedCompatable = isPredictedCompatable();
        return b == predictedCompatable;
    }

    public PotentialDate getMale()
    {
        return m_Male;
    }

    public PotentialDate getFemale()
    {
        return m_Female;
    }


    public boolean isCompatable()
    {
        return m_Compatable;
    }

    public void setCompatable(boolean pCompatable)
    {
        m_Compatable = pCompatable;
    }

    public boolean isPredictedCompatable()
    {
        if(m_PredictedCompatable == null)
            return false;
        return m_PredictedCompatable;
    }

    public void setPredictedCompatable(boolean pPredictedCompatable)
    {
        m_PredictedCompatable = pPredictedCompatable;
    }

    public double getDistance()
    {
        LatLon ml = getMale().getLatLon();
        LatLon fl = getFemale().getLatLon();
        if(ml == null || fl == null)
            return 0;
        double v = ml.distanceInKilometers(fl);
        if(Double.isNaN(v))
            return 0;
        return v;
    }

    public Set<String> getAllInterests()
    {
        Set<String> mi = getMale().getInterests();
        Set<String> fi = getFemale().getInterests();
        Set<String> allInterests = new HashSet<String>(mi);
        allInterests.addAll(fi);
        return allInterests;
    }

    public Set<String> getCommonInterests()
    {
        PotentialDate male = getMale();
        PotentialDate femalew = getFemale();
        String[] maleInterests = male.getInterests().toArray(new String[0]);
        String[] femaleInterests = femalew.getInterests().toArray(new String[0]);
        Set<String> mi = male.getInterests();
        Set<String> fi = femalew.getInterests();
        Set<String> allInterests = new HashSet<String>(mi);
        allInterests.retainAll(fi);
        String[] commonInterests = allInterests.toArray(new String[0]);
         return allInterests;
    }

    public int getMaleAge()
    {
        return getMale().getAge();
    }
    public int getFemaleAge()
    {
        return getFemale().getAge();
    }
    public boolean isMaleChildrenWanted()
    {
        return getMale().isChildrenWanted();
    }
    public boolean isFemaleChildrenWanted()
    {
        return getFemale().isChildrenWanted();
    }
    public boolean isMaleSmoker()
    {
        return getMale().isSmoker();
    }
    public boolean isFemaleSmoker()
    {
        return getFemale().isSmoker();
    }


    public String getTabbedLine()
    {
        StringBuilder sb = new StringBuilder();
        sb.append(isCompatable() ? "1":"0");
         sb.append("\t");

        sb.append(Integer.toString(getMaleAge()));
        sb.append("\t");
        sb.append(isMaleSmoker() ? "yes":"no");
        sb.append("\t");
        sb.append(isMaleChildrenWanted() ? "yes":"no");
        sb.append("\t");
        sb.append(getMale().getInterestsString());
        sb.append("\t");
        sb.append(getMale().getAddress());
        sb.append("\t");

        sb.append(Integer.toString(getFemaleAge()));
        sb.append("\t");
        sb.append(isFemaleSmoker() ? "yes":"no");
        sb.append("\t");
        sb.append(isFemaleChildrenWanted() ? "yes":"no");
        sb.append("\t");
        sb.append(getFemale().getInterestsString());
        sb.append("\t");
        sb.append(getFemale().getAddress());
        sb.append("\t");

        LatLon lon1 = getMale().getLatLon();
        String s = "NoLatLon";
        if(lon1 != null)
           s = lon1.toString();
        sb.append(s);
        sb.append("\t");

        LatLon lon = getFemale().getLatLon();
        s = "NoLatLon";
        if(lon != null)
              s = lon.toString();
        sb.append(s);
        sb.append("\t");

        double v = getDistance();
        DecimalFormat df = new DecimalFormat("###.#####");
        sb.append(df.format(v));
        sb.append("\t");
         return sb.toString();
    }
}
